package com.android.readcard.utils.djlm.newDJMLReader;

import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.support.v4.content.LocalBroadcastManager;

import com.android.readcard.utils.djlm.DJLMReader3.reader.HexUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;

/**
 * Created by Administrator on 2017/3/29.
 */
public class DJLM_USBHIDService {
    static DJLM_USBHIDService mDJLMUSBHIDService = null;
    public static DJLM_USBHIDService GetUSBHIDService(Context ctx)
    {
        if (mDJLMUSBHIDService == null)
            mDJLMUSBHIDService = new DJLM_USBHIDService(ctx);
        return mDJLMUSBHIDService;
    }

    DJLM_USBHIDService(Context ctx)
    {
        m_ctx = ctx;
    }

    private void broadcastUpdate(final String strData) {
        final Intent intent = new Intent("IDCardReader");
        intent.putExtra("IDCardReader", strData);
        LocalBroadcastManager.getInstance(m_ctx).sendBroadcast(intent);
    }

    UsbManager manager; // USB管理器
    UsbDevice mUsbDevice=null; // 找到的USB设备
    UsbInterface mInterface=null;
    UsbDeviceConnection mDeviceConnection;
    private Context m_ctx = null;

    boolean InitUsb() {
        broadcastUpdate("InitUsb");
        manager = (UsbManager) m_ctx.getSystemService(Context.USB_SERVICE);
        if (manager == null) {
            broadcastUpdate("manager = null");
            return false;
        } else {
            broadcastUpdate("usb设备：" + String.valueOf(manager.toString()));
        }
        HashMap deviceList = manager.getDeviceList();
        if (deviceList != null) {
            broadcastUpdate("usb设备：" + String.valueOf(deviceList.size()));
            Iterator deviceIterator = deviceList.values().iterator();
            ArrayList USBDeviceList = new ArrayList(); // 存放USB设备的数量
            while (deviceIterator.hasNext()) {
                UsbDevice device = (UsbDevice) deviceIterator.next();

                USBDeviceList.add(String.valueOf(device.getVendorId()));
                USBDeviceList.add(String.valueOf(device.getProductId()));

                broadcastUpdate(device.getVendorId() + " " + device.getProductId());
                // 在这里添加处理设备的代码
                if (device.getVendorId() == 0x0451 && device.getProductId() == 0x16B4) {
                    mUsbDevice = device;
                    broadcastUpdate("找到设备");
                    findIntfAndEpt(mUsbDevice, 1);
                    return true;
                }
            }
        } else {
            broadcastUpdate("deviceList = null");
        }
        return false;
    }

    boolean findIntfAndEpt(UsbDevice usbDevice, int nInterfaceID)
    {
        ////////////////////////////
        if (usbDevice == null) {
            broadcastUpdate("没有找到设备");
            return false;
        }
        for (int i = 0; i < usbDevice.getInterfaceCount();i++) {
// 获取设备接口，一般都是一个接口，你可以打印getInterfaceCount()方法查看接
// 口的个数，在这个接口上有两个端点，OUT 和 IN
            UsbInterface intf = usbDevice.getInterface(i);
            broadcastUpdate(i + " " + intf);
            if (intf.getId() == nInterfaceID) {
                mInterface = intf;
                break;
            }
        }
        if (mInterface != null) {
            UsbDeviceConnection connection = null;
// 判断是否有权限
            if (manager.hasPermission(usbDevice)) {
// 打开设备，获取 UsbDeviceConnection 对象，连接设备，用于后面的通讯
                connection = manager.openDevice(usbDevice);
                if (connection == null) {
                    return false;
                }
                if (connection.claimInterface(mInterface, true)) {
                    broadcastUpdate("找到接口");
                    mDeviceConnection = connection;
// 用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯
                    getEndpoint(mDeviceConnection, mInterface);
                } else {
                    connection.close();
                }
            } else {
                broadcastUpdate("没有权限");
            }
        } else {
            broadcastUpdate("没有找到接口");
        }
        return false;
    }

    private UsbEndpoint epOut;
    private UsbEndpoint epIn;
    // 用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯
    private void getEndpoint(UsbDeviceConnection connection, UsbInterface intf) {
        UsbEndpoint ep = intf.getEndpoint(0);
        if (ep != null) {
            if (ep.getAddress() >= 0x80)
                epIn = ep;
            else if (ep.getAddress() < 0x80)
                epOut = ep;
        }
        ep = intf.getEndpoint(1);
        if (ep != null) {
            if (ep.getAddress() >= 0x80)
                epIn = ep;
            else if (ep.getAddress() < 0x80)
                epOut = ep;
        }
    }

    int ReadWriteUSB(UsbDeviceConnection connection, UsbEndpoint endpointOut, UsbEndpoint endpointIn, int nSendPackLen, int nRecvPackLen, byte[] sendData, int nSendDataLen, byte[] recvData, int nTimeOut)
    {
        int ret = 0;
        byte[] retData = null;
        if (connection != null && endpointIn != null && endpointOut != null) {
            if (sendData != null && sendData.length > 0 && nSendDataLen > 0) {
                byte[] bt = new byte[nSendPackLen];
                Arrays.fill(bt, (byte) 0);
                System.arraycopy(sendData, 0, bt, 0, sendData.length);
                byte[] Sendbytes = Arrays.copyOf(bt, bt.length);
                ret = connection.bulkTransfer(endpointOut, Sendbytes, Sendbytes.length, nTimeOut);
                //broadcastUpdate("已经发送!");
                // 2,接收发送成功信息
                ret = connection.bulkTransfer(endpointIn, recvData, recvData.length, nTimeOut);
                return ret;
            }
        }
        return -1;
    }

    public byte[] USBIDioAccess(byte[] sendData, int nDataLen)
    {
        sendData = DJML_CommandItem.QueryBytesToStrig(sendData, nDataLen);
        byte[] rectData = new byte[64];
        int nRet = ReadWriteUSB(mDeviceConnection, epOut, epIn, 64, 64, sendData, nDataLen, rectData, 200);
        byte[] ret = null;
        if (nRet > 0)
            ret = DJML_CommandItem.ResponseStringToBytes(rectData, nRet);
        return ret;
    }

    void UsbTest() {
        if (mDeviceConnection != null && epOut != null && epIn != null) {
            broadcastUpdate("USB param OK! ");
            broadcastUpdate("epIn= " + epIn);
            broadcastUpdate("epOut= " + epOut);
            byte[] bt1 = new byte[]{'f', ' ', '0', '5', '0', '0', '0', '0'};
            byte[] retData = new byte[64];
            int nRet = ReadWriteUSB(mDeviceConnection, epOut, epIn, 64, 64, bt1,bt1.length, retData,  2000);
            String strRet = HexUtil.bytesToHexString(retData, nRet);
            broadcastUpdate(strRet);
        }
        else
        {
            if (mDeviceConnection == null)
            {
                broadcastUpdate("mDeviceConnection is null");
            }
            if (epOut == null)
            {
                broadcastUpdate("epOut is null");
            }
            if (epIn == null)
            {
                broadcastUpdate("epIn is null");
            }
        }
    }
}
